#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <signal.h>
#include <time.h>
#include <string.h>

#define BUFFER_SIZE 1024
#define DEFAULT_PORT 5000

volatile int running = 1;

void handle_sigint(int sig) {
    running = 0;
    printf("\n正在关闭服务器...\n");
    fflush(stdout);
}

void get_current_time(char *time_str) {
    time_t now = time(NULL);
    struct tm *tm_info = localtime(&now);
    strftime(time_str, 26, "%Y-%m-%d %H:%M:%S", tm_info);
}

int main(int argc, char *argv[]) {
    int server_sock, client_sock;
    struct sockaddr_in server_addr, client_addr;
    socklen_t client_len = sizeof(client_addr);
    char buffer[BUFFER_SIZE];
    char time_str[26];
    int port = DEFAULT_PORT;
    
    // 解析命令行参数
    if (argc > 1) {
        port = atoi(argv[1]);
    }
    
    // 设置信号处理
    struct sigaction sa;
    memset(&sa, 0, sizeof(sa));
    sa.sa_handler = handle_sigint;
    sigaction(SIGINT, &sa, NULL);
    sigaction(SIGTERM, &sa, NULL);
    
    // 创建socket
    server_sock = socket(AF_INET, SOCK_STREAM, 0);
    if (server_sock == -1) {
        perror("创建socket失败");
        return 1;
    }
    
    // 设置socket选项，允许地址重用
    int opt = 1;
    setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
    
    // 配置服务器地址
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(port);
    
    // 绑定socket
    if (bind(server_sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        perror("绑定失败");
        close(server_sock);
        return 1;
    }
    
    // 监听连接
    if (listen(server_sock, 5) < 0) {
        perror("监听失败");
        close(server_sock);
        return 1;
    }
    
    get_current_time(time_str);
    printf("[%s] TCP服务器启动成功，监听端口: %d\n", time_str, port);
    printf("等待虚拟串口连接...\n");
    
    while (running) {
        // 使用select来检查是否有连接请求，同时检查running标志
        fd_set readfds;
        struct timeval timeout;
        FD_ZERO(&readfds);
        FD_SET(server_sock, &readfds);
        timeout.tv_sec = 1;  // 1秒超时
        timeout.tv_usec = 0;
        
        int select_result = select(server_sock + 1, &readfds, NULL, NULL, &timeout);
        
        if (select_result > 0 && FD_ISSET(server_sock, &readfds)) {
            // 接受连接
            client_sock = accept(server_sock, (struct sockaddr*)&client_addr, &client_len);
            if (client_sock < 0) {
                if (running) {
                    perror("接受连接失败");
                }
                continue;
            }
        } else if (select_result < 0) {
            if (running) {
                perror("select失败");
            }
            continue;
        } else {
            // 超时，检查running标志
            if (!running) {
                break;
            }
            continue;
        }
        
        get_current_time(time_str);
        printf("[%s] 虚拟串口已连接: %s:%d\n", 
               time_str, 
               inet_ntoa(client_addr.sin_addr), 
               ntohs(client_addr.sin_port));
        
        // 处理客户端数据
        while (running) {
            // 使用select来检查是否有数据可读，同时检查running标志
            fd_set readfds_client;
            struct timeval timeout_client;
            FD_ZERO(&readfds_client);
            FD_SET(client_sock, &readfds_client);
            timeout_client.tv_sec = 1;  // 1秒超时
            timeout_client.tv_usec = 0;
            
            int select_result_client = select(client_sock + 1, &readfds_client, NULL, NULL, &timeout_client);
            
            if (select_result_client > 0 && FD_ISSET(client_sock, &readfds_client)) {
                int bytes_received = recv(client_sock, buffer, BUFFER_SIZE - 1, 0);
                if (bytes_received <= 0) {
                    if (bytes_received < 0) {
                        perror("接收数据失败");
                    }
                    break;
                }
            } else if (select_result_client < 0) {
                if (running) {
                    perror("select client失败");
                }
                break;
            } else {
                // 超时，检查running标志
                if (!running) {
                    break;
                }
                continue;
            }
            
            buffer[bytes_received] = '\0';
            get_current_time(time_str);
            printf("[%s] 收到数据 (%d字节): ", time_str, bytes_received);
            
            // 显示数据（十六进制和ASCII）
            printf("HEX: ");
            for (int i = 0; i < bytes_received; i++) {
                printf("%02X ", (unsigned char)buffer[i]);
            }
            printf(" | ASCII: ");
            for (int i = 0; i < bytes_received; i++) {
                if (buffer[i] >= 32 && buffer[i] <= 126) {
                    printf("%c", buffer[i]);
                } else {
                    printf(".");
                }
            }
            printf("\n");
            
            // 回显数据
            if (send(client_sock, buffer, bytes_received, 0) < 0) {
                perror("发送数据失败");
                break;
            }
            
            get_current_time(time_str);
            printf("[%s] 已回显数据\n", time_str);
        }
        
        get_current_time(time_str);
        printf("[%s] 虚拟串口断开连接\n", time_str);
        close(client_sock);
    }
    
    close(server_sock);
    get_current_time(time_str);
    printf("[%s] 服务器已关闭\n", time_str);
    
    return 0;
} 